二十一、SpringBoot2核心技术

您所在的位置:网站首页 activiti service 二十一、SpringBoot2核心技术

二十一、SpringBoot2核心技术

#二十一、SpringBoot2核心技术| 来源: 网络整理| 查看: 265

一、Activiti7与SpringBoot整合

Activiti7发布正式版之后,它与SpringBoot2.x已经完全支持整合开发。

1.1、SpringBoot整合Activiti7的配置

为了能够实现SpringBoot与Activiti7整合开发,首先我们要引入相关的依赖支持。 在工程的pom.xml文件中引入相关的依赖,其中activiti的依赖是:activiti-spring-boot-starter。 具体依赖如下所示:

4.0.0 com.xbmu springboot-activiti 1.0-SNAPSHOT org.springframework.boot spring-boot-starter-parent 2.1.0.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-jdbc org.springframework.boot spring-boot-starter-test org.activiti activiti-spring-boot-starter 7.0.0.Beta2 mysql mysql-connector-java 5.1.29 org.projectlombok lombok org.springframework.boot spring-boot-maven-plugin

通过该pom.xml文件所导入的坐标,我们就可以实现activiti7与Springboot整合。

1.2、SpringBoot的application.yml文件配置

为了能够实现Activiti7生成的表放到Mysql数据库中,需要在配置文件application.yml中添加相关的配置。 注意:activiti7默认没有开启数据库历史记录,需要手动配置开启。

spring: datasource: url: jdbc:mysql://127.0.0.1:3306/activiti?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT username: root password: root driver-class-name: com.mysql.jdbc.Driver activiti: # 1.false:默认值。activiti在启动时,对比数据库表中保存的版本,如果没有表或者版本不匹配,将抛出异常。 # 2.true:activiti会对数据库中所有表进行更新操作。如果表不存在,则自动创建 # 3.create-drop:在activiti启动时创建表,在关闭时删除表(必须手动关闭引擎,才能删除表) # 4.drop-create:在activiti启动时删除原来的旧表,然后在创建新表(不需要手动关闭引擎) # 检测历史表是否存在 activiti7 默认没有开启数据库历史记录 启动数据库历史记录 database-schema-update: true db-history-used: true # 记录历史等级 可配置的历史级别有 none、activity、audit、full # none:不保存任何的历史数据,因此,在流程执行过程中,这是最高效的。 # activity:级别高于none,保存流程实列与流程行为,其他数据不保存。 # audit:除了activity级别会保存的数据外,还会保存全部的流程任务及其属性。audit为history的默认值。 # full:保存历史数据的最高级别,除了会保存audit级别的数据外,还会保存其他全部流程相关的细节数据,包括一些流程参数等。 history-level: full # 校验流程文件,默认校验resource下processes文件夹里的流程文件。 # 自动部署验证设置:true-开启(默认)、false-关闭 check-process-definitions: true # 流程定义文件存放目录,默认路径为 classpath:/processes/ process-definition-location-prefix: classpath:/bpmn/ 1.3、 编写启动类 package com.xbmu; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class ActApplication { public static void main(String[] args) { SpringApplication.run(ActApplication.class,args); } } 1.4、添加SpringSecurity安全框架整合配置

因为Activiti7与SpringBoot整合后,默认情况下,集成了SpringSecurity安全框架,这样我们就要去准备SpringSecurity整合进来的相关用户权限配置信息。 SpringBoot的依赖包已经将SpringSecurity的依赖包也添加进项目中。 在这里插入图片描述

1.4.1、添加SecurityUtil类

为了能够快速实现SpringSecurity安全框架的配置,所添加的一个组件。 SecurityUtil.java

package com.xbmu.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextImpl; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.stereotype.Component; import java.util.Collection; @Component public class SecurityUtil { private Logger logger = LoggerFactory.getLogger(SecurityUtil.class); @Autowired @Qualifier("myUserDetailsService") private UserDetailsService userDetailsService; public void logInAs(String username) { UserDetails user = userDetailsService.loadUserByUsername(username); if (user == null) { throw new IllegalStateException("User " + username + " doesn't exist, please provide a valid user"); } logger.info("> Logged in as: " + username); SecurityContextHolder.setContext( new SecurityContextImpl( new Authentication() { @Override public Collection getAuthorities() { return user.getAuthorities(); } @Override public Object getCredentials() { return user.getPassword(); } @Override public Object getDetails() { return user; } @Override public Object getPrincipal() { return user; } @Override public boolean isAuthenticated() { return true; } @Override public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { } @Override public String getName() { return user.getUsername(); } })); org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(username); } }

这个类可以从我们下载的Activiti7官方提供的Example中找到。

1.4.2 添加DemoApplicationConfig类

在Activiti7官方下载的Example中找到DemoApplicationConfig类,它的作用是为了实现SpringSecurity框架的用户权限的配置,这样我们就可以在系统中使用用户权限信息。本次项目中基本是在文件中定义出来的用户信息,当然也可以是数据库中查询的用户权限信息。 后面处理流程时用到的任务负责人,需要添加在这里。 DemoApplicationConfig.java

package com.xbmu.config; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.test.context.ContextConfiguration; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; /** * 设置用户和角色 */ @Slf4j @Configuration public class DemoApplicationConfig { /** * 添加Security的用户 * * @return */ @Bean public UserDetailsService myUserDetailsService() { // 把用户存储在内存中 InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager(); // 构造用户的信息 String[][] usersGroupAndRoles = { {"jack", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"}, {"rose", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"}, {"tom", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"}, {"jerry", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"}, {"other", "password", "ROLE_ACTIVITI_USER", "GROUP_otherTeam"}, {"system", "password", "ROLE_ACTIVITI_USER"}, {"admin", "password", "ROLE_ACTIVITI_ADMIN"} }; for (String[] users : usersGroupAndRoles) { // 用户的角色和组 List authStrList = Arrays.asList(Arrays.copyOfRange(users, 2, users.length)); log.info("> Registering new user: {} with the following Authorities[{}]", users[0], authStrList); inMemoryUserDetailsManager.createUser(new User(users[0], passwordEncoder().encode(users[1]), authStrList.stream().map(str -> new SimpleGrantedAuthority(str)).collect(Collectors.toList()))); } return inMemoryUserDetailsManager; } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } } 1.5、创建Bpmn文件

Activiti7可以自动部署流程,前提是在resources目录下,创建一个新的目录processes,用来放置bpmn文件,也可以自定义存放目录。 创建一个简单的Bpmn流程文件,并设置任务的用户组Candidate Groups。 Candidate Groups中的内容与上面DemoApplicationConfiguration类中出现的用户组名称要保持一致,可以填写:activitiTeam 或者 otherTeam。 这样填写的好处:当不确定到底由谁来负责当前任务的时候,只要是Groups内的用户都可以拾取这个任务。 在这里插入图片描述 在这里插入图片描述

1.6、使用Junit方式测试 1.6.1、查看流程定义内容 package com.xbmu.test; import com.xbmu.util.SecurityUtil; import lombok.extern.slf4j.Slf4j; import org.activiti.api.process.model.ProcessDefinition; import org.activiti.api.process.model.ProcessInstance; import org.activiti.api.process.model.builders.ProcessPayloadBuilder; import org.activiti.api.process.runtime.ProcessRuntime; import org.activiti.api.runtime.shared.query.Page; import org.activiti.api.runtime.shared.query.Pageable; import org.activiti.api.task.model.Task; import org.activiti.api.task.model.builders.TaskPayloadBuilder; import org.activiti.api.task.runtime.TaskRuntime; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @Slf4j @RunWith(SpringRunner.class) @SpringBootTest public class TestActiviti { @Autowired private ProcessRuntime processRuntime; @Autowired private TaskRuntime taskRuntime; @Autowired private SecurityUtil securityUtil; /** * 查看流程定义内容 * Activiti7可以自动部署流程 */ @Test public void findProcess(){ securityUtil.logInAs("jack"); // 流程定义的分页对象 Page definitionPage = processRuntime.processDefinitions(Pageable.of(0, 10)); log.info("可用的流程定义总数:{}",definitionPage.getTotalItems()); for (ProcessDefinition processDefinition : definitionPage.getContent()) { System.out.println("=============================="); log.info("流程定义内容:{}",processDefinition); System.out.println("=============================="); } } }

在这里插入图片描述 在这里插入图片描述 act_re_procdef:流程定义表 在这里插入图片描述

1.6.2、启动流程 /** * 启动流程 */ @Test public void startProcess(){ // 设置登录用户 securityUtil.logInAs("system"); ProcessInstance processInstance = processRuntime. start(ProcessPayloadBuilder. start(). withProcessDefinitionKey("mydemo"). build()); log.info("流程实例的内容,{}",processInstance); }

在这里插入图片描述 act_ru_task:流程当前任务信息 在这里插入图片描述 act_ru_execution:流程执行信息 在这里插入图片描述

1.6.3、执行任务 /** * 执行任务 */ @Test public void doTask(){ // 设置登录用户 securityUtil.logInAs("jerry"); // 查询任务 Page taskPage = taskRuntime.tasks(Pageable.of(0, 10)); if(taskPage != null && taskPage.getTotalItems()>0){ for (Task task : taskPage.getContent()) { // 拾取任务 taskRuntime.claim(TaskPayloadBuilder. claim(). withTaskId(task.getId()). build()); log.info("任务内容,{}",task); // 完成任务 taskRuntime.complete(TaskPayloadBuilder. complete(). withTaskId(task.getId()). build()); } } }

在这里插入图片描述 在这里插入图片描述 act_hi_taskinst:流程任务的历史信息 在这里插入图片描述

/** * 执行任务 */ @Test public void doTask(){ // 设置登录用户 securityUtil.logInAs("rose"); // 查询任务 Page taskPage = taskRuntime.tasks(Pageable.of(0, 10)); if(taskPage != null && taskPage.getTotalItems()>0){ for (Task task : taskPage.getContent()) { // 拾取任务 taskRuntime.claim(TaskPayloadBuilder. claim(). withTaskId(task.getId()). build()); log.info("任务内容,{}",task); // 完成任务 taskRuntime.complete(TaskPayloadBuilder. complete(). withTaskId(task.getId()). build()); } }

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3